package com.gxa.ibear.handler;



import com.gxa.ibear.common.R;
import com.gxa.ibear.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolationException;

/**
 * 声明全局异常处理器，处理controller中的所以异常情况
 * 原理：基于AOP，所声明的环绕通知，结合目标切点（指向控制器中的方法）
 * spring实现的方法：
 * @ControllerAdvice 控制器的通知，感知到目标：控制器上的方法
 * @ExceptionHandler 声明通知中具体要执行的操作：捕获并处理异常
 * @RestControllerAdvice 聚合注解 包括ControllerAdvice 和 @ResponseBody
 *     作用类似catch，可以声明多个，但父类类型要放在最后
 * @author Lenovo
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
    /**
     * 处理业务异常方法
     * @param be 被注入的异常对象
     * @return
     */
    @ExceptionHandler(value = BizException.class)
    public R handleBizException(BizException be){
        Integer code = be.getErrorCode().getCode();
        return R.failed(code,be.getMessage());
    }


    /**
     * 处理业务异常方法
     * @param e 被注入的异常对象
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public R handleexception(Exception e){


        //TODO 开发阶段应该使用
//        e.printStackTrace();

        //获取所有的异常信息（ stcktrace / message / class）

        //lombok提供了一个@slf4j注解，去使用log对象
        String type = e.getClass().getSimpleName();
        log.info("------------------------------------"+type+"----------------------------");
        log.error(e.getClass().getSimpleName()+","+e.getMessage());

//        StackTraceElement[] stackTrace = e.getStackTrace();
//        for (StackTraceElement stackTraceElement : stackTrace) {
//            log.error(stackTraceElement.toString());
//        }
        log.info("------------------------------------"+type+"----------------------------");

        return R.failed("系统开小差了，请稍后再试");

    }

    @ExceptionHandler(value = ConstraintViolationException.class)
    public R handleBizexception(ConstraintViolationException e){
        return R.failed(e.getMessage());

    }
}
